unit uSBDUnit_JobMill;
interface
uses Classes, uSBDUnit_SyncObjects, SysUtils, Windows, uSBD_ServiceProvider;

type
TJobOption = (joPoisoned, joNoReturn);
TJobOptionSet = set of TJobOption;
ExceptionClass = class of Exception;

TBreatheProc = procedure ( var doAbortExecute: boolean) of object;

TJobReadyForPickup = packed record
    Msg: Cardinal;
    Dummy1, Dummy2: Longint;
    Result: Longint;
  end;

TJob = class abstract( TInterfacedPersistent)
  protected
    FExceptionClass: ExceptionClass;
    FExceptionMessage: string;
    FExceptionAt: pointer;

  public
    FOptions: TJobOptionSet;
    FOnBreatheProc: TBreatheProc;

    // Called in-thread
    procedure   Breathe( var doAbortExecute: boolean);
    procedure   Execute_InThread;        virtual; abstract;
    procedure   CaptureException( e1: Exception; Addr1: pointer);

    // Called out-of-thread
    constructor Create( Options1: TJobOptionSet);
    procedure   Execute_OutOfThread;     virtual;
    class procedure TimedOut;            virtual;
  end;



type
IJobMill = interface
  ['{0C2662B3-7531-4F3C-BF4B-3C01162B6F66}']
    {$REGION 'Property accessors'}
    procedure SetTimeOut( Value_ms: integer);
    procedure SetOnPollOutputThread( Value: TNotifyEvent);
    {$ENDREGION}
    procedure QueueJob( Job: TJob);
    function  WaitPop( TimeOut: integer = UsePropertyDefault): boolean;   // Return True if got a returned job.
    function  PeekPop: boolean;   // Return True if got a returned job.
    procedure KillThread;
    property  TimeOut_ms: integer    write SetTimeOut;
    property  OnPollOutputThread: TNotifyEvent  write SetOnPollOutputThread;
  end;

EAbortJob = class( Exception) end;

function AcquireJobMill( const Provider: IServiceProvider; const Config: string): IJobMill;

implementation







function AcquireJobMill( const Provider: IServiceProvider; const Config: string): IJobMill;
begin
Provider.Acquire( nil, IJobMill, result, Config)
end;


{ TJob }

procedure TJob.Breathe( var doAbortExecute: boolean);
begin
if assigned( FOnBreatheProc) then
    FOnBreatheProc( doAbortExecute)
  else
    doAbortExecute := False
end;


procedure TJob.CaptureException( e1: Exception; Addr1: pointer);
begin
FExceptionClass   := ExceptionClass( e1.ClassType);
FExceptionMessage := e1.Message;
FExceptionAt      := Addr1
end;

constructor TJob.Create( Options1: TJobOptionSet);
begin
FOptions := Options1
end;

procedure TJob.Execute_OutOfThread;
begin
end;



class procedure TJob.TimedOut;
begin
end;

end.
